package com.roc.template.cloud.factory.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.roc.template.cloud.AESEncryptor;
import com.roc.template.cloud.CloudConfig;
import com.roc.template.cloud.factory.*;
import com.roc.template.cloud.util.AccessTokenBean;
import com.roc.template.cloud.util.BasetTokenUtils;
import com.roc.template.cloud.util.HttpClientUtils;
import com.roc.template.utils.AESUtil;
import com.roc.template.utils.RSAEncrypt;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;


/**
 * @ClassName TeamAccessToken
 * @Description: TODO
 * @Author Administrator
 * @Date 2020/7/29 13 43
 * @Version V1.0
 **/
public class TeamAccessToken implements AccessToken {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    public String accessToken = null;
    public String refreshToken = null;
    public long expiredUntil = 0L;

    private CloudConfig cloudConfig;

    public TeamAccessToken(CloudConfig cloudConfig) {
        this.cloudConfig = cloudConfig;
    }

    @Override
    public void getAccesssToken() {
        JSONObject param = new JSONObject();
        param.put("appId", cloudConfig.appId);
        param.put("eid", cloudConfig.eid);
        param.put("secret",cloudConfig.appSecret);
        param.put("timestamp", System.currentTimeMillis());
        param.put("scope","team");

        String url = cloudConfig.outHost+"/gateway/oauth2/token/getAccessToken";
        String retString = HttpClientUtils.post(url, param.toJSONString());
        JSONObject jsonObject = JSON.parseObject(retString);
        logger.info("获取到accessToken:\n" + jsonObject);
        AccessTokenBean accessTokenBean = BasetTokenUtils.getParam(jsonObject);
        accessToken = accessTokenBean.getAccessToken();
        refreshToken = accessTokenBean.getRefreshToken();
        expiredUntil = accessTokenBean.getExpiredUntil();
    }

    @Override
    public void refreshAccessToken() {
        JSONObject param = new JSONObject();
        param.put("appId", cloudConfig.appId);
        param.put("eid", cloudConfig.eid);
        param.put("refreshToken", refreshToken);
        param.put("timestamp", System.currentTimeMillis());
        param.put("scope", "resGroupSecret");

        String url = cloudConfig.outHost+"/gateway/oauth2/token/refreshToken";
        String retString = HttpClientUtils.post(url, param.toJSONString());

        JSONObject jsonObject = JSON.parseObject(retString);
        logger.info("刷新accessToken:\n" + jsonObject);
        AccessTokenBean accessTokenBean = BasetTokenUtils.getParam(jsonObject);
        accessToken = accessTokenBean.getAccessToken();
        refreshToken = accessTokenBean.getRefreshToken();
        expiredUntil = accessTokenBean.getExpiredUntil();
    }


    public static Object pushBI() throws Exception {

        CommonDto commonDto = new CommonDto();
        commonDto.setArea("测试一区1");
        commonDto.setPredictAmount(333.5F);
        commonDto.setPreSaleCnt(20L);
        commonDto.setDistributionType("抵货款");
        commonDto.setPolicyStakeholder("经销商");
        commonDto.setPolicyEndDate("2021-02-05");
        commonDto.setPolicyObject("单店政策");
        commonDto.setPolicyStartDate("2021-02-05");
        commonDto.setPreCalWay("实销1");
        commonDto.setPolicyType("实销达量累计");
        commonDto.setPolicyTarget("主推");
        commonDto.setPredictFee(30000);
        commonDto.setPreSaleCnt(50L);

        Product product = new Product();
        product.setProductType("主推");

        List<Product> productList = new ArrayList<>();
        productList.add(product);

        commonDto.setProduct(productList);

        Dealer dealer = new Dealer();
        dealer.setDealerName("星沙一店");
        dealer.setDealerCode("C001");

        List<Dealer> dealers = new ArrayList<>();
        dealers.add(dealer);

        commonDto.setDealers(dealers);

        List<Condition> conditions = new ArrayList<>();
        Condition condition = new Condition();
        condition.setUpperNum(19);
        condition.setBonus(400);
        condition.setLowNum(15);
        conditions.add(condition);

        commonDto.setCondition(conditions);

//        List<Product> preProduct

        String common = "{\"area\":\"测试一区1\",\"predictAmount\":333.5,\"preSaleCnt\":20,\"product\":[{\"productType\":\"主推\"}],\"distributionType\":\"抵货款\",\"policyStakeholder\":\"经销商\",\"dealers\":[{\"dealerName\":\"星沙一店\",\"dealerCode\":\"C001\"},{\"dealerName\":\"星沙二店\",\"dealerCode\":\"C002\"}],\"policyEndDate\":\"2021-02-05\",\"policyObject\":\"单店政策\",\"policyStartDate\":\"2021-02-05\",\"preCalWay\":\"实销1\",\"condition\":[{\"upperNum\":19,\"bonus\":400,\"lowNum\":15},{\"upperNum\":24,\"bonus\":800,\"lowNum\":20},{\"upperNum\":29,\"bonusUnit\":50,\"bonus\":1000,\"rebateRatio\":30.6,\"lowNum\":25}],\"preProduct\":[{\"productType\":\"全部\"}],\"policyType\":\"实销达量累计\",\"id\":10000230,\"policyTarget\":\"主推\",\"predictFee\":30000,\"predictSaleCnt\":50}";

        JSONObject jsonObject1 = JSON.parseObject(common);

        int machineId = 1;

        int hashCodeV = UUID.randomUUID().toString().hashCode();
        if(hashCodeV < 0) {//有可能是负数
            hashCodeV = - hashCodeV;
        }
        String key = machineId + String.format("%015d", hashCodeV);

        Map<String, Object> sign = new HashMap<>();
        sign.put("ts", System.currentTimeMillis());
        sign.put("key",key);
        Map<String, Object> user = new HashMap<>();
        user.put("userName", "jindie");
        user.put("password", "111111");
        String signRSA = RSAEncrypt.encrypt(JSON.toJSONString(sign), RSAEncrypt.PUBLIC_KEY);
        String userAES = AESUtil.getEncryptedAES(JSON.toJSONString(user), key);
        JSONObject param = new JSONObject();
        param.put("common", jsonObject1.toJSONString());
        param.put("sign", signRSA);
        param.put("user", userAES);
        String url = "http://47.99.236.218:8088/api/v1/savePolicy";

        System.out.println(param.toJSONString());
        String retString = HttpClientUtils.post(url, param.toJSONString());
        System.out.println("推送返回值:"+ retString);
        JSONObject jsonObject = JSON.parseObject(retString);
        return jsonObject;
    }

    public static void main(String[] args) throws Exception {
        pushBI();
    }

    @Override
    public void checkAndRefreshAccessToken() {
        if (expiredUntil == 0L) {
            getAccesssToken();
        } else if (expiredUntil< 60L) {
            refreshAccessToken();
        }
    }

    /**
     * 获取审批痕迹
     * <p>
     * 参考:https://app.lzdcic.com/cloudflow-openplatform/other/3004
     *
     * @param param
     * @return
     */
    public JSONObject getFlowRecord(Map<String, String> param) {
        checkAndRefreshAccessToken();
        String url = cloudConfig.outHost+"/gateway/workflow/form/thirdpart/getFlowRecord?accessToken=";
        url += accessToken;
        String retString = HttpClientUtils.post(url, JSON.toJSONString(param));
        JSONObject jsonObject = JSON.parseObject(retString);
        logger.info("获取审批痕迹:\n" + jsonObject);
        return jsonObject;
    }

    /**
     * 发起审批
     * <p>
     * 参考:https://app.lzdcic.com/cloudflow-openplatform/other/3005
     *
     * @param param
     * @return
     */
    public JSONObject createInst(Map<String, Object> param) {
        checkAndRefreshAccessToken();
        String url = cloudConfig.outHost+"/gateway/workflow/form/thirdpart/createInst?accessToken=";
        url += accessToken;
        String retString = HttpClientUtils.post(url, JSON.toJSONString(param));
        JSONObject jsonObject = JSON.parseObject(retString);
        logger.info("发起审批:\n" + jsonObject);
        return jsonObject;
    }

    /**
     * 修改表单
     * <p>
     * 注意修改表单不要违反操作人所对应的节点字段权限，
     * 如不能编辑只读字段、必填字段必须要传等等
     * <p>
     * 参考:https://app.lzdcic.com/cloudflow-openplatform/other/3006'
     *
     * @param param
     * @return
     */
    public JSONObject modifyInst(Map<String, Object> param) {
        checkAndRefreshAccessToken();
        String url = cloudConfig.outHost+"/gateway/workflow/form/thirdpart/modifyInst?accessToken=";
        url += accessToken;
        String retString = HttpClientUtils.post(url, JSON.toJSONString(param));
        JSONObject jsonObject = JSON.parseObject(retString);
        logger.info("修改表单:" + jsonObject);
        return jsonObject;
    }

    /**
     * 获取使用了互联控件的模版列表
     * <p>
     * 参考:https://app.lzdcic.com/cloudflow-openplatform/other/3001
     *
     * @param param
     * @return
     */
    public JSONObject getTemplateListByGroupId(Map<String, Object> param) {
        checkAndRefreshAccessToken();
        String url = cloudConfig.outHost+"/gateway/workflow/form/thirdpart/getByGroupId?accessToken=";
        url += accessToken;
        String retString = HttpClientUtils.post(url, JSON.toJSONString(param));
        JSONObject jsonObject = JSON.parseObject(retString);
        logger.info("获取使用了互联控件的模版列表:\n" + jsonObject);
        return jsonObject;
    }

    /**
     * 获取模版
     * <p>
     * 参考:https://app.lzdcic.com/cloudflow-openplatform/other/3002
     *
     * @param param
     * @return
     */
    public JSONObject getTemplateByCodeId(Map<String, String> param) {
        checkAndRefreshAccessToken();
        String url = cloudConfig.outHost+"/gateway/workflow/form/thirdpart/viewFormDef?accessToken=";
        url += accessToken;
        String retString = HttpClientUtils.post(url, JSON.toJSONString(param));
        JSONObject jsonObject = JSON.parseObject(retString);
        logger.info("获取模版:\n" + jsonObject);
        return jsonObject;
    }

    /**
     * 解密推送数据()
     * <p>
     * 参考:https://app.lzdcic.com/cloudflow-openplatform/external/2003
     *
     * @param cipher
     * @return
     */
    public JSONObject decryptNotification(String cipher) {
        if (cipher == null || cipher.isEmpty()) {
            return null;
        }

        AESEncryptor encryptor = new AESEncryptor(cloudConfig.key);
        String plainText = encryptor.decrypt(cipher);
        return JSON.parseObject(plainText);
    }

    /**
     * 获取审批状态
     * <p>
     * 参考:https://app.lzdcic.com/cloudflow-openplatform/other/3010
     *
     * @param param
     * @return
     */
    public JSONObject getFlowStatus(Map<String, String> param) {
        checkAndRefreshAccessToken();
        String url = cloudConfig.outHost+"/gateway/workflow/form/thirdpart/getFlowStatus?accessToken=";
        url += accessToken;
        String retString = HttpClientUtils.post(url, JSON.toJSONString(param));
        JSONObject jsonObject = JSON.parseObject(retString);
        logger.info("获取审批状态:\n" + jsonObject);
        return jsonObject;
    }

    /**
     * 获取流程监控可查询模板
     * <p>
     * 参考:https://app.lzdcic.com/cloudflow-openplatform/other/3012
     *
     * @param param
     * @return
     */
    public JSONObject getTemplates(Map<String, Object> param) {
        checkAndRefreshAccessToken();
        String url = cloudConfig.outHost+"/gateway/workflow/form/thirdpart/getTemplates?accessToken=";
        url += accessToken;
        String retString = HttpClientUtils.post(url, JSON.toJSONString(param));
        JSONObject jsonObject = JSON.parseObject(retString);
        logger.info("获取模板:\n" + jsonObject);
        return jsonObject;
    }




    /**
     * 获取流程数据
     * <p>
     * 参考:https://app.lzdcic.com/cloudflow-openplatform/other/3013
     *
     * @param param
     * @return
     */
    public JSONObject findFlows(Map<String, Object> param) {
        checkAndRefreshAccessToken();
        String url = cloudConfig.outHost+"/gateway/workflow/form/thirdpart/findFlows?accessToken=";
        url += accessToken;
        String retString = HttpClientUtils.post(url, JSON.toJSONString(param));
        JSONObject jsonObject = JSON.parseObject(retString);
        logger.info("获取流程列表:\n" + jsonObject);
        return jsonObject;
    }

}
